{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<!--NAVIGATION-->\n",
    "< [In Depth: Gaussian Mixture Models](05.12-Gaussian-Mixtures.ipynb) | [Contents](Index.ipynb) | [Application: A Face Detection Pipeline](05.14-Image-Features.ipynb) >\n",
    "\n",
    "<a href=\"https://colab.research.google.com/github/jakevdp/PythonDataScienceHandbook/blob/master/notebooks/05.13-Kernel-Density-Estimation.ipynb\"><img align=\"left\" src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open in Colab\" title=\"Open and Execute in Google Colaboratory\"></a>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# In-Depth: Kernel Density Estimation\n",
    "\n",
    "# 深入：核密度估计"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "> In the previous section we covered Gaussian mixture models (GMM), which are a kind of hybrid between a clustering estimator and a density estimator.\n",
    "Recall that a density estimator is an algorithm which takes a $D$-dimensional dataset and produces an estimate of the $D$-dimensional probability distribution which that data is drawn from.\n",
    "The GMM algorithm accomplishes this by representing the density as a weighted sum of Gaussian distributions.\n",
    "*Kernel density estimation* (KDE) is in some senses an algorithm which takes the mixture-of-Gaussians idea to its logical extreme: it uses a mixture consisting of one Gaussian component *per point*, resulting in an essentially non-parametric estimator of density.\n",
    "In this section, we will explore the motivation and uses of KDE.\n",
    "\n",
    "在上一节中我们介绍了高斯混合模型（GMM），它是一种介于聚类评估器和密度评估器的混合模型。回忆一下密度评估器的定义，这是一种从$D$维数据集中产生一个$D$为概率分布的算法。GMM算法使用了加权高斯分布和的方式实现了密度评估器。*核密度估计*在某种程度上是一个将高斯混合理念发展到其逻辑层次的算法：该算法是包含了每个数据点形成的一个高斯成分，得到一个基本上无参数的密度评估器。在本节中，我们会讨论和密度分析KDE的原理和应用。\n",
    "\n",
    "> We begin with the standard imports:\n",
    "\n",
    "导入包："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns; sns.set()\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Motivating KDE: Histograms\n",
    "\n",
    "## 初探KDE：直方图\n",
    "\n",
    "> As already discussed, a density estimator is an algorithm which seeks to model the probability distribution that generated a dataset.\n",
    "For one dimensional data, you are probably already familiar with one simple density estimator: the histogram.\n",
    "A histogram divides the data into discrete bins, counts the number of points that fall in each bin, and then visualizes the results in an intuitive manner.\n",
    "\n",
    "前面已经讨论过，密度评估器是一种找到样本概率分布的模型，用以生成数据集的算法。对于一维数据而言，你应该已经熟悉其中一种简单的密度评估器：直方图。直方图将数据分成离散的桶，计算每个通中数据点的数量，然后将结果可视化成一张非常直观的图表。\n",
    "\n",
    "> For example, let's create some data that is drawn from two normal distributions:\n",
    "\n",
    "例如下面我们构建一些数据形成两个正态分布："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def make_data(N, f=0.3, rseed=1):\n",
    "    rand = np.random.RandomState(rseed)\n",
    "    x = rand.randn(N)\n",
    "    x[int(f * N):] += 5\n",
    "    return x\n",
    "\n",
    "x = make_data(1000)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> We have previously seen that the standard count-based histogram can be created with the ``plt.hist()`` function.\n",
    "By specifying the ``normed`` parameter of the histogram, we end up with a normalized histogram where the height of the bins does not reflect counts, but instead reflects probability density:\n",
    "\n",
    "前面我们已经看到标准的直方图可以使用`plt.hist()`函数绘制。通过设置`density`参数，我们可以将直方图标准化，这时图像的高度不再代表数据点的数量，而是概率密度：\n",
    "\n",
    "译者注：新版Matplotlib已经不再使用normed参数，原文和代码中的参数名称已经修改为density。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "hist = plt.hist(x, bins=30, density=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Notice that for equal binning, this normalization simply changes the scale on the y-axis, leaving the relative heights essentially the same as in a histogram built from counts.\n",
    "This normalization is chosen so that the total area under the histogram is equal to 1, as we can confirm by looking at the output of the histogram function:\n",
    "\n",
    "注意对上图来说，标准化只是修改了y轴的度量，但是每个桶相对高度与使用计数构建的直方图是一致的。标准化能够使得直方图的全部面积加起来等于1，因此我们可以通过直方图函数的输出结果来进行验证："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "density, bins, patches = hist\n",
    "widths = bins[1:] - bins[:-1]\n",
    "(density * widths).sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> One of the issues with using a histogram as a density estimator is that the choice of bin size and location can lead to representations that have qualitatively different features.\n",
    "For example, if we look at a version of this data with only 20 points, the choice of how to draw the bins can lead to an entirely different interpretation of the data!\n",
    "Consider this example:\n",
    "\n",
    "使用直方图作为密度评估器的一个问题是桶大小和位置的选择会导致展现出不同的数据特征。例如我们仅仅使用20个数据点的情况下，如何划分桶的选择会得到完全不同的数据解释。如下例："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = make_data(20)\n",
    "bins = np.linspace(-5, 10, 10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 864x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(1, 2, figsize=(12, 4),\n",
    "                       sharex=True, sharey=True,\n",
    "                       subplot_kw={'xlim':(-4, 9),\n",
    "                                   'ylim':(-0.02, 0.3)})\n",
    "fig.subplots_adjust(wspace=0.05)\n",
    "for i, offset in enumerate([0.0, 0.6]):\n",
    "    ax[i].hist(x, bins=bins + offset, density=True)\n",
    "    ax[i].plot(x, np.full_like(x, -0.01), '|k',\n",
    "               markeredgewidth=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> On the left, the histogram makes clear that this is a bimodal distribution.\n",
    "On the right, we see a unimodal distribution with a long tail.\n",
    "Without seeing the preceding code, you would probably not guess that these two histograms were built from the same data: with that in mind, how can you trust the intuition that histograms confer?\n",
    "And how might we improve on this?\n",
    "\n",
    "左边的直方图很明显是一个双峰分布。右边的直方图却是一个单峰缝补。如果不是看到了前面的代码，我们可能会猜测这两个直方图是从不同的数据集获得的：在这种情况下，我们如何能信任直方图给我们关于数据分布的直觉呢？我们该如何改进这点呢？\n",
    "\n",
    "> Stepping back, we can think of a histogram as a stack of blocks, where we stack one block within each bin on top of each point in the dataset.\n",
    "Let's view this directly:\n",
    "\n",
    "回头看一下，我们可以将直方图想象成方块组成的堆，我们可以将数据集中的每个数据点都堆一块放置到其从属的桶的最上方。我们来看看："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "bins = np.arange(-3, 8)\n",
    "ax.plot(x, np.full_like(x, -0.1), '|k',\n",
    "        markeredgewidth=1)\n",
    "for count, edge in zip(*np.histogram(x, bins)):\n",
    "    for i in range(count):\n",
    "        ax.add_patch(plt.Rectangle((edge, i), 1, 1,\n",
    "                                   alpha=0.5))\n",
    "ax.set_xlim(-4, 8)\n",
    "ax.set_ylim(-0.2, 8);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> The problem with our two binnings stems from the fact that the height of the block stack often reflects not on the actual density of points nearby, but on coincidences of how the bins align with the data points.\n",
    "This mis-alignment between points and their blocks is a potential cause of the poor histogram results seen here.\n",
    "But what if, instead of stacking the blocks aligned with the *bins*, we were to stack the blocks aligned with the *points they represent*?\n",
    "If we do this, the blocks won't be aligned, but we can add their contributions at each location along the x-axis to find the result.\n",
    "Let's try this:\n",
    "\n",
    "刚才看到那两个直方图的问题实质在于，方块组成的堆高度通常反映的不是实际的附近数据点密度，而是取决于桶与数据点对齐的选择方式，这具有一定的偶然性。不合适的选择就是我们前面看到不正确的直方图结果的原因。但是如果我们不是将方块叠放到桶上，而是将方块叠放到它们*所代表的数据点*上会怎么样？这样做的话，这些方块不会对齐，我们可以将每个数据点在x轴的每个位置上的贡献叠加起来得到结果。例如："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "x_d = np.linspace(-4, 8, 2000)\n",
    "density = sum((abs(xi - x_d) < 0.5) for xi in x)\n",
    "\n",
    "plt.fill_between(x_d, density, alpha=0.5)\n",
    "plt.plot(x, np.full_like(x, -0.1), '|k', markeredgewidth=1)\n",
    "\n",
    "plt.axis([-4, 8, -0.2, 8]);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> The result looks a bit messy, but is a much more robust reflection of the actual data characteristics than is the standard histogram.\n",
    "Still, the rough edges are not aesthetically pleasing, nor are they reflective of any true properties of the data.\n",
    "In order to smooth them out, we might decide to replace the blocks at each location with a smooth function, like a Gaussian.\n",
    "Let's use a standard normal curve at each point instead of a block:\n",
    "\n",
    "结果看起来有点乱，但是它能比标准直方图更加鲁棒地反映数据的特征。然而图中的坚硬边界很不美观，且它们也无法反映数据的真实属性。我们可以考虑使用光滑的函数，比方说高斯函数，来平滑这个图形。下面我们在每个电商使用使用标准正态曲线来取代叠放的方块："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from scipy.stats import norm\n",
    "x_d = np.linspace(-4, 8, 1000)\n",
    "density = sum(norm(xi).pdf(x_d) for xi in x)\n",
    "\n",
    "plt.fill_between(x_d, density, alpha=0.5)\n",
    "plt.plot(x, np.full_like(x, -0.1), '|k', markeredgewidth=1)\n",
    "\n",
    "plt.axis([-4, 8, -0.2, 5]);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> This smoothed-out plot, with a Gaussian distribution contributed at the location of each input point, gives a much more accurate idea of the shape of the data distribution, and one which has much less variance (i.e., changes much less in response to differences in sampling).\n",
    "\n",
    "平滑后的图像，在每个输入点上都是高斯分布，能够提供对于数据分布的更加精确的形状，而且具有更少的差异（例如取样不同产生的差异小了许多）。\n",
    "\n",
    "> These last two plots are examples of kernel density estimation in one dimension: the first uses a so-called \"tophat\" kernel and the second uses a Gaussian kernel.\n",
    "We'll now look at kernel density estimation in more detail.\n",
    "\n",
    "后面这两张图就是核密度估计在一维数据上的例子：第一幅图使用的是“高帽”核，第二幅图使用的是高斯核。下面我们详细讨论核密度估计。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Kernel Density Estimation in Practice\n",
    "\n",
    "## 实践中使用核密度估计\n",
    "\n",
    "> The free parameters of kernel density estimation are the *kernel*, which specifies the shape of the distribution placed at each point, and the *kernel bandwidth*, which controls the size of the kernel at each point.\n",
    "In practice, there are many kernels you might use for a kernel density estimation: in particular, the Scikit-Learn KDE implementation supports one of six kernels, which you can read about in Scikit-Learn's [Density Estimation documentation](http://scikit-learn.org/stable/modules/density.html).\n",
    "\n",
    "核密度估计中的自由参数是*核*，它设定了分布在每个点的形状以及控制着每个点上核大小的*核带宽*。实践中有许多可用的核密度估计：具体来说，Scikit-Learn的KDE实现了其中的6种，读者可以在Scikit-Learn在线文档[密度估计](http://scikit-learn.org/stable/modules/density.html)中查看。\n",
    "\n",
    "> While there are several versions of kernel density estimation implemented in Python (notably in the SciPy and StatsModels packages), I prefer to use Scikit-Learn's version because of its efficiency and flexibility.\n",
    "It is implemented in the ``sklearn.neighbors.KernelDensity`` estimator, which handles KDE in multiple dimensions with one of six kernels and one of a couple dozen distance metrics.\n",
    "Because KDE can be fairly computationally intensive, the Scikit-Learn estimator uses a tree-based algorithm under the hood and can trade off computation time for accuracy using the ``atol`` (absolute tolerance) and ``rtol`` (relative tolerance) parameters.\n",
    "The kernel bandwidth, which is a free parameter, can be determined using Scikit-Learn's standard cross validation tools as we will soon see.\n",
    "\n",
    "虽然Python当中有一些核密度估计的实现（主要是在SciPy和StatsModels包中），作者还是建议使用Scikit-Learn的版本，因为它的高效和灵活性。这些评估器被实现在`sklearn.neighbors.KernelDensity`当中，它们能使用6种核类型以及数十种距离度量计算方法在多维数据中实现KDE。因为KDE方法较为计算密集，Scikit-Learn的评估器在底层使用了树形算法，并且能够使用`atol`（绝对容差）和`rtol`（相对容差）来平衡计算时间与精确度。自由参数核带宽可以使用标准的交叉验证工具决定，我们马上就会看到。\n",
    "\n",
    "> Let's first show a simple example of replicating the above plot using the Scikit-Learn ``KernelDensity`` estimator:\n",
    "\n",
    "下面使用Scikit-Learn的`KernelDensity`评估器重复一下上面的图表，作为一个简单的例子："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from sklearn.neighbors import KernelDensity\n",
    "\n",
    "# 初始化KDE模型，拟合数据\n",
    "kde = KernelDensity(bandwidth=1.0, kernel='gaussian')\n",
    "kde.fit(x[:, None])\n",
    "\n",
    "# score_samples返回概率密度的对数值\n",
    "logprob = kde.score_samples(x_d[:, None])\n",
    "\n",
    "plt.fill_between(x_d, np.exp(logprob), alpha=0.5)\n",
    "plt.plot(x, np.full_like(x, -0.01), '|k', markeredgewidth=1)\n",
    "plt.ylim(-0.02, 0.22);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> The result here is normalized such that the area under the curve is equal to 1.\n",
    "\n",
    "上面的结果已经标准化了，因此曲线下方的面积和为1。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Selecting the bandwidth via cross-validation\n",
    "\n",
    "### 通过交叉验证选择带宽\n",
    "\n",
    "> The choice of bandwidth within KDE is extremely important to finding a suitable density estimate, and is the knob that controls the bias–variance trade-off in the estimate of density: too narrow a bandwidth leads to a high-variance estimate (i.e., over-fitting), where the presence or absence of a single point makes a large difference. Too wide a bandwidth leads to a high-bias estimate (i.e., under-fitting) where the structure in the data is washed out by the wide kernel.\n",
    "\n",
    "KDE中带宽的选择对于寻找合适的密度估计是至关重要的，同时也是控制偏差的开关，这是密度估计方差的权衡值：太窄的带宽会导致高方差估计（也就是过拟合），可以认为一个数据点的存在或缺失会导致巨大的差异。太宽泛的带宽会导致高偏差估计（也就是欠拟合），整个数据的结构被过宽的核给抹平了。\n",
    "\n",
    "> There is a long history in statistics of methods to quickly estimate the best bandwidth based on rather stringent assumptions about the data: if you look up the KDE implementations in the SciPy and StatsModels packages, for example, you will see implementations based on some of these rules.\n",
    "\n",
    "在统计学中，基于数据相当严格的假设来估计最佳带宽有着很长的历史：如果你查看SciPy和StatsModels包中的KDE实现，你可以看到其中一些规则的实现。\n",
    "\n",
    "> In machine learning contexts, we've seen that such hyperparameter tuning often is done empirically via a cross-validation approach.\n",
    "With this in mind, the ``KernelDensity`` estimator in Scikit-Learn is designed such that it can be used directly within the Scikit-Learn's standard grid search tools.\n",
    "Here we will use ``GridSearchCV`` to optimize the bandwidth for the preceding dataset.\n",
    "Because we are looking at such a small dataset, we will use leave-one-out cross-validation, which minimizes the reduction in training set size for each cross-validation trial:\n",
    "\n",
    "在机器学习领域，我们已经知道这样的超参数调整通常可以通过交叉验证方法来实现。因此Scikit-Learn中的`KernelDensity`评估器被设计成可以直接使用Scikit-Learn的标准网格搜索工具。这里我们将使用`GridSearchCV`来对前面的数据集的带宽进行优化。因为这是一个非常小的数据集，我们会使用留出一个的交叉验证方法，这能在每次交叉验证测试中尽量保证训练集的最大样本量：\n",
    "\n",
    "译者注：新版Scikit-Learn已经将GridSearchCV和LeaveOneOut移到了`sklearn.model_selection`包中，并且LeaveOneOut不再需要提供参数。下面的代码做了相应修改。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.model_selection import LeaveOneOut\n",
    "\n",
    "bandwidths = 10 ** np.linspace(-1, 1, 100)\n",
    "grid = GridSearchCV(KernelDensity(kernel='gaussian'),\n",
    "                    {'bandwidth': bandwidths},\n",
    "                    cv=LeaveOneOut())\n",
    "grid.fit(x[:, None]);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Now we can find the choice of bandwidth which maximizes the score (which in this case defaults to the log-likelihood):\n",
    "\n",
    "现在我们就可以得到最大分值的带宽了（在这个例子中默认是分值的对数）："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'bandwidth': 1.1233240329780276}"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grid.best_params_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> The optimal bandwidth happens to be very close to what we used in the example plot earlier, where the bandwidth was 1.0 (i.e., the default width of ``scipy.stats.norm``).\n",
    "\n",
    "带宽的最优值正好非常接近我们在前面例子中使用的1.0（也就是`scipy.stats.norm`的默认宽度）。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example: KDE on a Sphere\n",
    "\n",
    "## 例子：球面上的KDE\n",
    "\n",
    "> Perhaps the most common use of KDE is in graphically representing distributions of points.\n",
    "For example, in the Seaborn visualization library (see [Visualization With Seaborn](04.14-Visualization-With-Seaborn.ipynb)), KDE is built in and automatically used to help visualize points in one and two dimensions.\n",
    "\n",
    "也许KDE最常见的应用就是数据点分布的图像表示。例如在Seaborn可视化库（参见[使用Seaborn可视化](04.14-Visualization-With-Seaborn.ipynb)）中，KDE是在一维和二维空间中的內建自动化可视化方法。\n",
    "\n",
    "> Here we will look at a slightly more sophisticated use of KDE for visualization of distributions.\n",
    "We will make use of some geographic data that can be loaded with Scikit-Learn: the geographic distributions of recorded observations of two South American mammals, *Bradypus variegatus* (the Brown-throated Sloth) and *Microryzomys minutus* (the Forest Small Rice Rat).\n",
    "\n",
    "这里我们将要讨论一个稍微复杂一些的KDE进行数据分布可视化的例子：观察记录到两种南美哺乳动物的地理分布情况，棕喉树懒和森林小稻鼠。\n",
    "\n",
    "> With Scikit-Learn, we can fetch this data as follows:\n",
    "\n",
    "使用Scikit-Learn如下获取数据："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.datasets import fetch_species_distributions\n",
    "\n",
    "data = fetch_species_distributions()\n",
    "\n",
    "# 提取物种ID和位置数据\n",
    "latlon = np.vstack([data.train['dd lat'],\n",
    "                    data.train['dd long']]).T\n",
    "species = np.array([d.decode('ascii').startswith('micro')\n",
    "                    for d in data.train['species']], dtype='int')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> With this data loaded, we can use the Basemap toolkit (mentioned previously in [Geographic Data with Basemap](04.13-Geographic-Data-With-Basemap.ipynb)) to plot the observed locations of these two species on the map of South America.\n",
    "\n",
    "当数据载入后，我们可以使用Basemap工具集（之前在[使用Basemap创建地理位置图表](04.13-Geographic-Data-With-Basemap.ipynb)中介绍过）来绘制这两个物种在南美洲地图上观测的位置。\n",
    "\n",
    "译者注：译者所用Matplotlib 3.1版本有个bug，basemap中__init__方法会抛出警告，master分支已经修复，但未并入发行版，此处保留了该警告，但不影响后续功能"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/wangy/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:9: MatplotlibDeprecationWarning: \n",
      "The dedent function was deprecated in Matplotlib 3.1 and will be removed in 3.3. Use inspect.cleandoc instead.\n",
      "  if __name__ == '__main__':\n",
      "/home/wangy/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:13: MatplotlibDeprecationWarning: \n",
      "The dedent function was deprecated in Matplotlib 3.1 and will be removed in 3.3. Use inspect.cleandoc instead.\n",
      "  del sys.path[0]\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from mpl_toolkits.basemap import Basemap\n",
    "from sklearn.datasets.species_distributions import construct_grids\n",
    "\n",
    "xgrid, ygrid = construct_grids(data)\n",
    "\n",
    "# 使用basemap绘制海岸线\n",
    "m = Basemap(projection='cyl', resolution='c',\n",
    "            llcrnrlat=ygrid.min(), urcrnrlat=ygrid.max(),\n",
    "            llcrnrlon=xgrid.min(), urcrnrlon=xgrid.max())\n",
    "m.drawmapboundary(fill_color='#DDEEFF')\n",
    "m.fillcontinents(color='#FFEEDD')\n",
    "m.drawcoastlines(color='gray', zorder=2)\n",
    "m.drawcountries(color='gray', zorder=2)\n",
    "\n",
    "# 绘制位置\n",
    "m.scatter(latlon[:, 1], latlon[:, 0], zorder=3,\n",
    "          c=species, cmap='rainbow', latlon=True);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Unfortunately, this doesn't give a very good idea of the density of the species, because points in the species range may overlap one another.\n",
    "You may not realize it by looking at this plot, but there are over 1,600 points shown here!\n",
    "\n",
    "不过，上图并没有给出这两种动物的分布密度估计，因为这些点的范围互相重叠了。观察上图可以看到很多分布点，但是实际上有超过1600个数据点绘制在图中。\n",
    "\n",
    "> Let's use kernel density estimation to show this distribution in a more interpretable way: as a smooth indication of density on the map.\n",
    "Because the coordinate system here lies on a spherical surface rather than a flat plane, we will use the ``haversine`` distance metric, which will correctly represent distances on a curved surface.\n",
    "\n",
    "让我们使用核密度估计将这个分布展示成更加有含义的图表：在地图上显示平滑的密度分布情况。因为实际上使用的是球面坐标系统而不是平面坐标系，所以距离度量采取了`haversine`，这是一个能正确表达曲面距离的方法。\n",
    "\n",
    "> There is a bit of boilerplate code here (one of the disadvantages of the Basemap toolkit) but the meaning of each code block should be clear:\n",
    "\n",
    "下面的代码有点冗长（Basemap工具集的缺点之一），但是每个代码块的含义还是很清晰的："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/wangy/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:20: MatplotlibDeprecationWarning: \n",
      "The dedent function was deprecated in Matplotlib 3.1 and will be removed in 3.3. Use inspect.cleandoc instead.\n",
      "/home/wangy/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:23: MatplotlibDeprecationWarning: \n",
      "The dedent function was deprecated in Matplotlib 3.1 and will be removed in 3.3. Use inspect.cleandoc instead.\n",
      "/home/wangy/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:20: MatplotlibDeprecationWarning: \n",
      "The dedent function was deprecated in Matplotlib 3.1 and will be removed in 3.3. Use inspect.cleandoc instead.\n",
      "/home/wangy/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:23: MatplotlibDeprecationWarning: \n",
      "The dedent function was deprecated in Matplotlib 3.1 and will be removed in 3.3. Use inspect.cleandoc instead.\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 设置地图上的数据网格\n",
    "X, Y = np.meshgrid(xgrid[::5], ygrid[::5][::-1])\n",
    "land_reference = data.coverages[6][::5, ::5]\n",
    "land_mask = (land_reference > -9999).ravel()\n",
    "xy = np.vstack([Y.ravel(), X.ravel()]).T\n",
    "xy = np.radians(xy[land_mask])\n",
    "\n",
    "# 创建两个并排的图表\n",
    "fig, ax = plt.subplots(1, 2)\n",
    "fig.subplots_adjust(left=0.05, right=0.95, wspace=0.05)\n",
    "species_names = ['Bradypus Variegatus', 'Microryzomys Minutus']\n",
    "cmaps = ['Purples', 'Reds']\n",
    "\n",
    "for i, axi in enumerate(ax):\n",
    "    axi.set_title(species_names[i])\n",
    "    \n",
    "    # 使用basemap绘制海岸线和国境线\n",
    "    m = Basemap(projection='cyl', llcrnrlat=Y.min(),\n",
    "                urcrnrlat=Y.max(), llcrnrlon=X.min(),\n",
    "                urcrnrlon=X.max(), resolution='c', ax=axi)\n",
    "    m.drawmapboundary(fill_color='#DDEEFF')\n",
    "    m.drawcoastlines()\n",
    "    m.drawcountries()\n",
    "    \n",
    "    # 构造分布的球面核密度估计\n",
    "    kde = KernelDensity(bandwidth=0.03, metric='haversine')\n",
    "    kde.fit(np.radians(latlon[species == i]))\n",
    "\n",
    "    # 仅计算陆地范围，-9999代表海洋\n",
    "    Z = np.full(land_mask.shape[0], -9999.0)\n",
    "    Z[land_mask] = np.exp(kde.score_samples(xy))\n",
    "    Z = Z.reshape(X.shape)\n",
    "\n",
    "    # 绘制密度的轮廓\n",
    "    levels = np.linspace(0, Z.max(), 25)\n",
    "    axi.contourf(X, Y, Z, levels=levels, cmap=cmaps[i])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Compared to the simple scatter plot we initially used, this visualization paints a much clearer picture of the geographical distribution of observations of these two species.\n",
    "\n",
    "对比前面我们绘制的简单散点图，上面两个图表很清晰的展示了两种动物的地理位置分布情况。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example: Not-So-Naive Bayes\n",
    "\n",
    "## 例子：不那么朴素的贝叶斯\n",
    "\n",
    "> This example looks at Bayesian generative classification with KDE, and demonstrates how to use the Scikit-Learn architecture to create a custom estimator.\n",
    "\n",
    "下面这个例子我们来看下使用KDE创建贝叶斯生成分类，并且展示如何使用Scikit-Learn创建自定义的评估器。\n",
    "\n",
    "> In [In Depth: Naive Bayes Classification](05.05-Naive-Bayes.ipynb), we took a look at naive Bayesian classification, in which we created a simple generative model for each class, and used these models to build a fast classifier.\n",
    "For Gaussian naive Bayes, the generative model is a simple axis-aligned Gaussian.\n",
    "With a density estimation algorithm like KDE, we can remove the \"naive\" element and perform the same classification with a more sophisticated generative model for each class.\n",
    "It's still Bayesian classification, but it's no longer naive.\n",
    "\n",
    "在[深入：朴素贝叶斯分类](05.05-Naive-Bayes.ipynb)中，我们学习了朴素贝叶斯分类，里面构建了每个类别的简单生成模型并且使用这些模型来构建一个快速分类器。对于高斯朴素贝叶斯来说，生成模型就是简单的沿着坐标轴的高斯函数。使用密度估计算法如KDE，我们可以去除其中的“朴素”成分，然后对每个类别使用更加复杂的生成模型进行相同的分类工作。这仍然是贝叶斯分类，只是不再朴素。\n",
    "\n",
    "> The general approach for generative classification is this:\n",
    "\n",
    ">1. Split the training data by label.\n",
    "2. For each set, fit a KDE to obtain a generative model of the data.\n",
    "   This allows you for any observation $x$ and label $y$ to compute a likelihood $P(x~|~y)$.   \n",
    "3. From the number of examples of each class in the training set, compute the *class prior*, $P(y)$.\n",
    "4. For an unknown point $x$, the posterior probability for each class is $P(y~|~x) \\propto P(x~|~y)P(y)$.\n",
    "   The class which maximizes this posterior is the label assigned to the point.\n",
    "\n",
    "生成分类的通用方法如下：\n",
    "\n",
    "1. 将训练数据依据标签划分成不同类别。\n",
    "2. 对每个类别，使用KDE拟合数据获得一个生成模型。这允许你对于任何观察$x$和标签$y$计算出似然$P(x~|~y)$。\n",
    "3. 对训练集中的每个类别，从样本数量计算得到*类别先验概率*$P(y)$。\n",
    "4. 对一个未知点$x$，每个类别的后验概率是$P(y~|~x) \\propto P(x~|~y)P(y)$。哪个类别具有最大的后验概率值，就将这个点设置为该类别标签。\n",
    "\n",
    "> The algorithm is straightforward and intuitive to understand; the more difficult piece is couching it within the Scikit-Learn framework in order to make use of the grid search and cross-validation architecture.\n",
    "\n",
    "上述算法很直观和易于理解；更困难的部分是将它实现在Scikit-Learn框架当中，这样就能使用网格搜索和交叉验证工具。\n",
    "\n",
    "> This is the code that implements the algorithm within the Scikit-Learn framework; we will step through it following the code block:\n",
    "\n",
    "下面是Scikit-Learn框架中实现这个算法的代码；我们过一遍这些代码片段："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.base import BaseEstimator, ClassifierMixin\n",
    "\n",
    "\n",
    "class KDEClassifier(BaseEstimator, ClassifierMixin):\n",
    "    \"\"\"Bayesian generative classification based on KDE\n",
    "    \n",
    "    Parameters\n",
    "    ----------\n",
    "    bandwidth : float\n",
    "        the kernel bandwidth within each class\n",
    "    kernel : str\n",
    "        the kernel name, passed to KernelDensity\n",
    "    \"\"\"\n",
    "    def __init__(self, bandwidth=1.0, kernel='gaussian'):\n",
    "        self.bandwidth = bandwidth\n",
    "        self.kernel = kernel\n",
    "        \n",
    "    def fit(self, X, y):\n",
    "        self.classes_ = np.sort(np.unique(y))\n",
    "        training_sets = [X[y == yi] for yi in self.classes_]\n",
    "        self.models_ = [KernelDensity(bandwidth=self.bandwidth,\n",
    "                                      kernel=self.kernel).fit(Xi)\n",
    "                        for Xi in training_sets]\n",
    "        self.logpriors_ = [np.log(Xi.shape[0] / X.shape[0])\n",
    "                           for Xi in training_sets]\n",
    "        return self\n",
    "        \n",
    "    def predict_proba(self, X):\n",
    "        logprobs = np.array([model.score_samples(X)\n",
    "                             for model in self.models_]).T\n",
    "        result = np.exp(logprobs + self.logpriors_)\n",
    "        return result / result.sum(1, keepdims=True)\n",
    "        \n",
    "    def predict(self, X):\n",
    "        return self.classes_[np.argmax(self.predict_proba(X), 1)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The anatomy of a custom estimator\n",
    "\n",
    "### 自定义评估器剖析"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Let's step through this code and discuss the essential features:\n",
    "\n",
    "让我们一步一步的分析上面的代码并讨论其中最关键的特性：\n",
    "\n",
    "```python\n",
    "from sklearn.base import BaseEstimator, ClassifierMixin\n",
    "\n",
    "class KDEClassifier(BaseEstimator, ClassifierMixin):\n",
    "    \"\"\"Bayesian generative classification based on KDE\n",
    "    \n",
    "    Parameters\n",
    "    ----------\n",
    "    bandwidth : float\n",
    "        the kernel bandwidth within each class\n",
    "    kernel : str\n",
    "        the kernel name, passed to KernelDensity\n",
    "    \"\"\"\n",
    "```\n",
    "\n",
    "> Each estimator in Scikit-Learn is a class, and it is most convenient for this class to inherit from the ``BaseEstimator`` class as well as the appropriate mixin, which provides standard functionality.\n",
    "For example, among other things, here the ``BaseEstimator`` contains the logic necessary to clone/copy an estimator for use in a cross-validation procedure, and ``ClassifierMixin`` defines a default ``score()`` method used by such routines.\n",
    "We also provide a doc string, which will be captured by IPython's help functionality (see [Help and Documentation in IPython](01.01-Help-And-Documentation.ipynb)).\n",
    "\n",
    "Scikit-Learn中的每个评估器都是一个类（译者注：Python类），对于评估器类来说最方便的就是继承`BaseEstimator`类以及相应的混合器，它们能提供标准的功能。例如这里`BaseEstimator`包含着代码逻辑当需要使用交叉验证过程时能复制评估器的副本，`ClassifierMixin`定义了默认的`score()`方法给分类器继承。下面是文档字符串，可以被IPython的帮助功能捕获到（参见[IPython的帮助和文档](01.01-Help-And-Documentation.ipynb)）。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Next comes the class initialization method:\n",
    "\n",
    "下面是类实例初始化方法：\n",
    "\n",
    "```python\n",
    "    def __init__(self, bandwidth=1.0, kernel='gaussian'):\n",
    "        self.bandwidth = bandwidth\n",
    "        self.kernel = kernel\n",
    "```\n",
    "\n",
    "> This is the actual code that is executed when the object is instantiated with ``KDEClassifier()``.\n",
    "In Scikit-Learn, it is important that *initialization contains no operations* other than assigning the passed values by name to ``self``.\n",
    "This is due to the logic contained in ``BaseEstimator`` required for cloning and modifying estimators for cross-validation, grid search, and other functions.\n",
    "Similarly, all arguments to ``__init__`` should be explicit: i.e. ``*args`` or ``**kwargs`` should be avoided, as they will not be correctly handled within cross-validation routines.\n",
    "\n",
    "这个方法的代码是当对象实例通过`KDEClassifier()`创建完成后初始化执行的部分。在Scikit-Learn中，很重要的一点需要记住，初始化方法除了通过`self`设置对象属性外不能包括其他的操作。这是因为`BaseEstimator`中的代码逻辑在交叉验证、网格搜索和其他功能时需要克隆和修改评估器。类似的，`__init__`方法的参数应该是显示定义的：`*args`或`**kwargs`的定义方式应该避免，同样是因为它们无法被交叉验证过程正确的处理。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Next comes the ``fit()`` method, where we handle training data:\n",
    "\n",
    "接下来是`fit()`方法，这里进行数据拟合：\n",
    "\n",
    "```python \n",
    "    def fit(self, X, y):\n",
    "        self.classes_ = np.sort(np.unique(y))\n",
    "        training_sets = [X[y == yi] for yi in self.classes_]\n",
    "        self.models_ = [KernelDensity(bandwidth=self.bandwidth,\n",
    "                                      kernel=self.kernel).fit(Xi)\n",
    "                        for Xi in training_sets]\n",
    "        self.logpriors_ = [np.log(Xi.shape[0] / X.shape[0])\n",
    "                           for Xi in training_sets]\n",
    "        return self\n",
    "```\n",
    "\n",
    "> Here we find the unique classes in the training data, train a ``KernelDensity`` model for each class, and compute the class priors based on the number of input samples.\n",
    "Finally, ``fit()`` should always return ``self`` so that we can chain commands. For example:\n",
    "\n",
    "首先找出训练数据中所有唯一的分类标签，对每个分类独立训练一个`KernelDensity`模型，然后根据输入样本数量计算每个分类的先验概率。最后`fit()`方法应该永远返回`self`令其支持链式操作。例如：\n",
    "\n",
    "```python\n",
    "label = model.fit(X, y).predict(X)\n",
    "```\n",
    "\n",
    "> Notice that each persistent result of the fit is stored with a trailing underscore (e.g., ``self.logpriors_``).\n",
    "This is a convention used in Scikit-Learn so that you can quickly scan the members of an estimator (using IPython's tab completion) and see exactly which members are fit to training data.\n",
    "\n",
    "注意一下`fit`得到的持久化结果应该保存在后缀下划线名称的属性当中（例如`self.logpriors_`）。这是Scikit-Learn的编码规范方便用户迅速的查看评估器的成员值（使用IPython的制表符补全）并获得已经拟合到训练数据上的成员变量值。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Finally, we have the logic for predicting labels on new data:\n",
    "\n",
    "最后我们看到的是在新数据上预测标签的逻辑：\n",
    "\n",
    "```python\n",
    "    def predict_proba(self, X):\n",
    "        logprobs = np.vstack([model.score_samples(X)\n",
    "                              for model in self.models_]).T\n",
    "        result = np.exp(logprobs + self.logpriors_)\n",
    "        return result / result.sum(1, keepdims=True)\n",
    "        \n",
    "    def predict(self, X):\n",
    "        return self.classes_[np.argmax(self.predict_proba(X), 1)]\n",
    "```\n",
    "\n",
    "> Because this is a probabilistic classifier, we first implement ``predict_proba()`` which returns an array of class probabilities of shape ``[n_samples, n_classes]``.\n",
    "Entry ``[i, j]`` of this array is the posterior probability that sample ``i`` is a member of class ``j``, computed by multiplying the likelihood by the class prior and normalizing.\n",
    "\n",
    "因为这是一个概率分类器，我们首先实现了`predict_proba()`方法，它返回新数据在每个分类上的后验概率数组，形状是`[n_samples, n_classes]`。数组中的元素`[i, j]`是样本`i`属于分类`j`的后验概率值，通过将似然值与分类先验概率值相乘并标准化后得到。\n",
    "\n",
    "> Finally, the ``predict()`` method uses these probabilities and simply returns the class with the largest probability.\n",
    "\n",
    "最后`predict()`方法使用这些概率并在其中找到最大值，然后返回分类的标签。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Using our custom estimator\n",
    "\n",
    "### 使用我们的自定义评估器\n",
    "\n",
    "> Let's try this custom estimator on a problem we have seen before: the classification of hand-written digits.\n",
    "Here we will load the digits, and compute the cross-validation score for a range of candidate bandwidths using the ``GridSearchCV`` meta-estimator (refer back to [Hyperparameters and Model Validation](05.03-Hyperparameters-and-Model-Validation.ipynb)):\n",
    "\n",
    "让我们试一下这个自定义评估器，使用前面我们研究过的问题：手写数字分类。我们载入手写数字数据，然后针对一定范围的带宽值使用`GridSearchCV`元评估器计算交叉验证结果（参见[超参数和模型验证](05.03-Hyperparameters-and-Model-Validation.ipynb)）：\n",
    "\n",
    "译者注：下面代码做了修改以适应新版本Scikit-Learn。包括GridSearchCV从属的包，参数cv和结果中使用cv_result_字典取分值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/wangy/anaconda3/lib/python3.7/site-packages/sklearn/model_selection/_search.py:813: DeprecationWarning: The default of the `iid` parameter will change from True to False in version 0.22 and will be removed in 0.24. This will change numeric results when test-set sizes are unequal.\n",
      "  DeprecationWarning)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.datasets import load_digits\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "\n",
    "digits = load_digits()\n",
    "\n",
    "bandwidths = 10 ** np.linspace(0, 2, 100)\n",
    "grid = GridSearchCV(KDEClassifier(), {'bandwidth': bandwidths}, cv=5)\n",
    "grid.fit(digits.data, digits.target)\n",
    "\n",
    "scores = grid.cv_results_['mean_test_score']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Next we can plot the cross-validation score as a function of bandwidth:\n",
    "\n",
    "接下来我们可以绘制交叉验证分值与带宽之间的函数图像："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'bandwidth': 4.641588833612779}\n",
      "accuracy = 0.9677239844184753\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.semilogx(bandwidths, scores)\n",
    "plt.xlabel('bandwidth')\n",
    "plt.ylabel('accuracy')\n",
    "plt.title('KDE Model Performance')\n",
    "print(grid.best_params_)\n",
    "print('accuracy =', grid.best_score_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> We see that this not-so-naive Bayesian classifier reaches a cross-validation accuracy of just over 96%; this is compared to around 80% for the naive Bayesian classification:\n",
    "\n",
    "我们看到这个不那么朴素的贝叶斯分类器达到了交叉验证准确率超过96%；与朴素贝叶斯分类的大约80%比较："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.8065207555552298"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.naive_bayes import GaussianNB\n",
    "from sklearn.model_selection import cross_val_score\n",
    "cross_val_score(GaussianNB(), digits.data, digits.target, cv=5).mean()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> One benefit of such a generative classifier is interpretability of results: for each unknown sample, we not only get a probabilistic classification, but a *full model* of the distribution of points we are comparing it to!\n",
    "If desired, this offers an intuitive window into the reasons for a particular classification that algorithms like SVMs and random forests tend to obscure.\n",
    "\n",
    "这样的生成分类器的一个优点是结果的可解释性：对于每个未知的样本，我们不但得到了概率分类，还获得了数据点分布情况的*完整模型*。如果需要的话，这可以提供一个样本具体分类的直观理由，而其他算法像SVM和随机森林通常是模糊的。\n",
    "\n",
    "> If you would like to take this further, there are some improvements that could be made to our KDE classifier model:\n",
    "\n",
    "> - we could allow the bandwidth in each class to vary independently\n",
    "- we could optimize these bandwidths not based on their prediction score, but on the likelihood of the training data under the generative model within each class (i.e. use the scores from ``KernelDensity`` itself rather than the global prediction accuracy)\n",
    "\n",
    "如果你希望更进一步，下面是我们KDE分类模型可以继续优化的一些建议：\n",
    "\n",
    "- 我们可以允许每个分类使用独立的带宽值。\n",
    "- 我们可以优化带宽值，不基于它们的预测分数，而是基于每个分类在生成模型下拟合训练数据的似然值（也就是使用`KernelDensity`本身的分数值来调整带宽，而不是全局的预测准确率）。\n",
    "\n",
    "> Finally, if you want some practice building your own estimator, you might tackle building a similar Bayesian classifier using Gaussian Mixture Models instead of KDE.\n",
    "\n",
    "最后，如果你希望练习构建你自己的评估器，你可以尝试一个相似的贝叶斯分类器，使用高斯混合模型而不是KDE。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<!--NAVIGATION-->\n",
    "< [In Depth: Gaussian Mixture Models](05.12-Gaussian-Mixtures.ipynb) | [Contents](Index.ipynb) | [Application: A Face Detection Pipeline](05.14-Image-Features.ipynb) >\n",
    "\n",
    "<a href=\"https://colab.research.google.com/github/jakevdp/PythonDataScienceHandbook/blob/master/notebooks/05.13-Kernel-Density-Estimation.ipynb\"><img align=\"left\" src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open in Colab\" title=\"Open and Execute in Google Colaboratory\"></a>\n"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
